<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // call  apply   bind  => 改变this的指向(所有的函数都可以使用  => 函数的拓展方法)

    // new Function()
    // function fn() { // 函数也可以理解为是一个实例化对象

    // }
    // console.dir(fn)

    // 函数也可以理解为是一个实例化对象 => 构造函数Function创建的 => 可以访问Function.prototype公有的属性和方法
    // console.log(fn.constructor === Function);
    // console.log(fn.__proto__ === Function.prototype);


    // -------------------------------------------------------------------------

    // call  apply   bind 

    // call(thisObj,arg1,arg2,....argN)
    // 1. 调用原函数
    // 2. 在本次函数执行过程中,强制将this指向call()的第一参数,如果第一参数是null和undefined => 只是调用原函数,并不改变this指向
    // 3. 如果原函数需要接收参数,则从call()的第二参数开始依次向后传

    // apply(thisObj,[arg1,arg2,....argN])
    // 1. 调用原函数
    // 2. 在本次函数执行过程中,强制将this指向apply()的第一参数,如果第一参数是null和undefined => 只是调用原函数,并不改变this指向
    // 3. 如果原函数需要接收参数,先将参数依次整合到数组中,再将数组作为第二参数传入

    // 总结: 借用原函数执行一次,对原函数没有影响 (借鸡生蛋)



    function fn(a, b) {
        console.log("this", this);
        console.log("参数", a, b);
    }

    // fn();  // 普通调用 this -> window

    // 1. 调用原函数
    // fn.call();

    // 2. 在本次函数执行过程中,强制将this指向call()的第一参数
    // fn.call(null);
    // fn.call(undefined);
    // fn.call(1);

    // 3. 如果函数需要参数,则从call()的第二参数开始依次向后传
    // fn.call(document.body, 1, 2);

    // fn.apply();
    // fn.apply(1);
    // fn.apply(null);
    // fn.apply(document, [100, 200])








</script>

</html>